home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / dev / src / rot3dsrc.lha / rot3d / rot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-11  |  37.1 KB  |  1,351 lines

  1.  
  2. /************************************************************************
  3. * Rot.c -- main program file.
  4. *
  5. * Amiga demo of texture-mapped walls.
  6. *   - 2 16 color palettes
  7. *     - variable light-sourcing
  8. *   - adjustable view size
  9. *   - doors, secret doors
  10. *   - lores/hires auto switching
  11. *   - Walls created from pieces of other walls.
  12. *
  13. * Compiles under Aztec & SAS (with small mods to makefile).
  14. * 1993 by: Jason Freund, Gabe Dalbec, Chris Hames.
  15. *
  16. ************************************************************************/
  17.  
  18. #ifdef    __SASC
  19. #include "includes.h"
  20. #define    MYFAR    __far
  21. /*
  22. #define float double
  23. */
  24. #else
  25. #define    MYFAR
  26. #endif
  27. #include "walls.h"
  28. /*#include "objdat.h"*/
  29. #include "defines.h"
  30.  
  31. short halfres=0;
  32. short moveok=1;
  33. UBYTE *heighttolight;
  34. extern UBYTE heighttolight0[];
  35. extern UBYTE heighttolight1[];
  36. extern UBYTE heighttolight2[];
  37. extern UBYTE heighttolight3[];
  38. extern UBYTE heighttolight4[];
  39. extern UBYTE heighttolight5[];
  40. extern UBYTE heighttolight6[];
  41. extern unsigned long lighttable_base[];
  42. unsigned long *lighttable;
  43. extern void makelightcolor(void);
  44. extern UWORD wallparts[];
  45.  
  46. /* You must be running Kickstart 2.0+ to define timing */
  47. #define TIMING
  48. #ifdef TIMING
  49. #include <devices/timer.h>
  50. #define StartTTimer()    ReadEClock(&TimerStuff->ttime1)
  51. #define EndTTimer()    { ReadEClock(&TimerStuff->ttime2); printf("%f frames/sec\n",(float)Frames/((TimerStuff->ttime2.ev_lo-TimerStuff->ttime1.ev_lo)/(float)TimerStuff->EFreq)); }
  52. #define StartTimer()    ReadEClock(&TimerStuff->time1)
  53. #define EndTimer(a)    { ReadEClock(&TimerStuff->time2); printf("%s took %f seconds\n",a,(TimerStuff->time2.ev_lo-TimerStuff->time1.ev_lo)/(float)TimerStuff->EFreq); }
  54. struct Library *TimerBase=NULL;
  55. struct MyTimerStuff
  56.   {
  57.   struct timerequest tio;
  58.   struct EClockVal ttime1;
  59.   struct EClockVal ttime2;
  60.   struct EClockVal time1;
  61.   struct EClockVal time2;
  62.   ULONG EFreq;
  63.   };
  64. struct MyTimerStuff *TimerStuff=NULL;
  65. #else
  66. #define StartTTimer()    ;
  67. #define EndTTimer()    ;
  68. #define StartTimer()    ;
  69. #define EndTimer(a)    ;
  70. #endif
  71.  
  72. short screenx,screeny;
  73. struct IntuitionBase *IntuitionBase=NULL;
  74. struct GfxBase       *GfxBase=NULL;
  75. struct Screen        *Screen;
  76. struct Screen        *mapscreen;
  77. struct Window        *mapwindow;
  78. struct RastPort      *maprp;
  79. struct Window        *FirstWindow;
  80. struct RastPort      *rp;
  81. struct View          *view;
  82. struct RasInfo       dualri;
  83. struct BitMap        bm1,fastbm,mapbm;
  84. struct IntuiMessage  *message;
  85. ULONG *rowlookLR;
  86. ULONG *rowlookHR;
  87. ULONG *rowlook;
  88. unsigned char lines[352/8];
  89. short brushno=0;
  90. char filename[100];
  91. float angle;
  92. float cy;
  93. float sy;
  94. float points[MAXPOINTS][3];
  95. float subpoints[MAXPOINTS][3];
  96. float rotpoints[MAXPOINTS][3];
  97. struct UCopList *uCopList = NULL;
  98. ULONG Frames=0;
  99. UBYTE lightcolor[353];
  100. short numpoints=0;
  101. UBYTE edges[MAXEDGES][3];
  102. short numedges=0;
  103. UBYTE poly[MAXPOLY][4];
  104. short numpoly=0;
  105. float transX=0,transY=0;
  106. short wallwidth = WALLWIDTH;
  107. BOOL speed=1;
  108. short bitmapno=0;
  109. int numlines;
  110. short delx;
  111. int x2,y2;
  112. short torch=3;
  113. short dely;
  114. short numbuttons=0;
  115. short e;
  116. short x;
  117. short y;
  118. short interchange,s1,s2;
  119. short Sx,Sy,Dx,Dy,m1,m2;
  120. short intowall=0,outofwall=0;
  121. short changepalette,lastpalette=0;
  122. extern Brush *Items[4][NUMITEMS+1];
  123. extern Brush *Misc[NUMMISC+1];
  124. /*extern void BlitMe(short x, short y, Brush *b);*/
  125. typedef struct
  126. {
  127.     UWORD height;
  128.     short bitmap;
  129.     short offset;
  130.     short junk;
  131. } mapline;
  132. mapline map[353];
  133.  
  134. struct ExtNewScreen SuperScreen =
  135. {
  136.    0, 0,                /* LeftEdge, TopEdge   */
  137.    352, 199,            /* Width, Height       */
  138.    DEPTH,               /* Depth               */
  139.    0, 1,                /* DetailPen, BlockPen */
  140.    0,                /* ViewModes           */
  141.    CUSTOMSCREEN |       /* Type                */
  142.    SCREENQUIET | CUSTOMBITMAP | NS_EXTENDED,
  143.    NULL,                /* Font                */
  144.    NULL,
  145.    NULL,                /* Gadgets             */
  146.    NULL,                /* CustomBitMap        */
  147.    NULL,                /* Extend */
  148. };
  149.  
  150. struct NewWindow FirstNewWindow =
  151. {
  152.    0, 0,             /* LeftEdge, TopEdge   */
  153.    353, 199,            /* Width, Height       */
  154.    0, 1,                /* DetailPen, BlockPen */
  155.    MENUPICK | ACTIVEWINDOW | MOUSEBUTTONS |
  156.    VANILLAKEY | MOUSEMOVE ,/* IDCMP flags  */
  157.    BACKDROP |BORDERLESS | NOCAREREFRESH |
  158.    ACTIVATE | RMBTRAP | REPORTMOUSE ,       /* general flags   */
  159.    NULL,                /* First Gadget        */
  160.    NULL,                /* CheckMark           */
  161.    NULL,
  162.    NULL,                /* Screen              */
  163.    NULL,                /* BitMap              */
  164.    100, 50,             /* Min Width, Height   */
  165.    640, 400,            /* Max Width, Height   */
  166.    CUSTOMSCREEN,        /* Type                */
  167. };
  168.  
  169. /**************************************************************************
  170. * Maps not currently used.
  171. **************************************************************************/
  172. struct NewScreen MapNewScreen =
  173. {
  174.    0, 0,                /* LeftEdge, TopEdge   */
  175.    320, 80,            /* Width, Height       */
  176.    5,               /* Depth               */
  177.    0, 1,                /* DetailPen, BlockPen */
  178.    0,        /* ViewModes           */
  179.    CUSTOMSCREEN |       /* Type                */
  180.    SCREENQUIET | CUSTOMBITMAP,
  181.    NULL,                /* Font                */
  182.    NULL,
  183.    NULL,                /* Gadgets             */
  184.    NULL,                /* CustomBitMap        */
  185. };
  186.  
  187. struct NewWindow MapNewWindow =
  188. {
  189.    0, 0,             /* LeftEdge, TopEdge   */
  190.    320, 80,            /* Width, Height       */
  191.    0, 1,                /* DetailPen, BlockPen */
  192.    0,/* IDCMP flags  */
  193.    BACKDROP |BORDERLESS | NOCAREREFRESH |
  194.    RMBTRAP,       /* general flags   */
  195.    NULL,                /* First Gadget        */
  196.    NULL,                /* CheckMark           */
  197.    NULL,
  198.    NULL,                /* Screen              */
  199.    NULL,                /* BitMap              */
  200.    100, 50,             /* Min Width, Height   */
  201.    640, 400,            /* Max Width, Height   */
  202.    CUSTOMSCREEN,        /* Type                */
  203. };
  204.  
  205.  
  206. /**************************************************************************
  207. * rot.c routine definitions
  208. **************************************************************************/
  209. void LoadCopper(void);
  210. void SetUpMap(void);
  211. void PlotYou(void);
  212. void PlotMap(void);
  213. void PlotRotMap(void);
  214. void SubDivide(void);
  215. void MakeTables(void);
  216. void ToggleRes(void);
  217. void DrawScene(void);
  218. void Close_All(void);
  219. void Open_All(BOOL reopen,short oldx, short oldy);
  220. void ReadScene(void);
  221. void Line(float sx,float sy,float dx,float dy);
  222.  
  223. /**************************************************************************
  224. * Assembly routine definitions
  225. **************************************************************************/
  226.  
  227. /*
  228. Sets an are of memory to zero. mem be word aligned or 68020+.
  229. size must be a multiple of 4 */
  230. extern void cpuclear(void *mem,long size);
  231. extern void cpuclear2(void *mem,long size);
  232. extern void fasttochip(struct BitMap *bm);
  233. extern void fasttochip2(struct BitMap *bm);
  234. extern void Fill(void);
  235. void MegaMap(short Sx, short delx, short x, short y);
  236.  
  237. /**************************************************************************
  238. * BlitFill.  val is whether or not screen starts with top or bottom palette
  239. * This routine fills the fifth bitplane with 1s and 0s alternately after
  240. * every vertical line (see blitline, below).
  241. *
  242. * This routine is now used, but will probably later be done during the
  243. * copy-out phase with the cpu because 1) the cpu is probably faster since
  244. * the loop is already set up 2) Doing it in the copy-out phase will
  245. * get rid of the flickering caused by doing 4 planes all at once, and then
  246. * the fifth plane afterwards.
  247. *
  248. * Not used
  249. **************************************************************************/
  250. void BlitFill(BOOL val)
  251. {
  252.     UWORD blitsize;
  253.     UWORD height=rp->BitMap->Rows;
  254.     UWORD width=SBYTESPERROW;
  255.     void *mem=rp->BitMap->Planes[4]+width*height-2;
  256.     UWORD con1val=(val) ? 0x000e : 0x000a;
  257.     struct Custom *custom = (void *)0x00dff000;
  258.     blitsize=height*64+width/2;
  259.     OwnBlitter();
  260.     WaitBlit();
  261.     custom->bltcon0 = 0x09f0;
  262.     custom->bltcon1 = con1val;
  263.     custom->bltdmod = 0;
  264.     custom->bltamod = 0;
  265.     custom->bltdpt = (APTR)mem;
  266.     custom->bltapt = (APTR)mem;
  267.     custom->bltsize = blitsize;
  268.     DisownBlitter();
  269. }
  270.  
  271. UBYTE *htab[] =
  272. {
  273.     &heighttolight0[0],
  274.     &heighttolight1[0],
  275.     &heighttolight2[0],
  276.     &heighttolight3[0],
  277.     &heighttolight4[0],
  278.     &heighttolight5[0],
  279.     &heighttolight6[0],
  280. };
  281.  
  282.  
  283. short ie,currented,myedge,nexted;
  284. short nextanim[] = {1,2,3,4,5,6,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
  285. short animwalls1[25] = { 1,3,7,9,10,13,15,16,20,34,55,56,57,60};
  286. short animwalls2[5] = { 5 ,50};
  287. short delay=0;
  288. /*************************************************************************
  289. * Increments edge number for all animating walls in animwalls[].
  290. *************************************************************************/
  291. void AnimWalls()
  292. {
  293. /* Drip Anim */
  294.     nexted = edges[1][2]+1;
  295.     if (nexted>6) nexted=1;
  296.     for (ie=0;ie<14;ie++) edges[animwalls1[ie]][2]=nexted;
  297.  
  298. /* OTB Anim */
  299.     nexted = edges[5][2]+1;
  300.     if (nexted>12) nexted=7;
  301.     for (ie=0;ie<2;ie++) edges[animwalls2[ie]][2]=nexted;
  302. }
  303.  
  304. /*************************************************************************
  305. * Change brightness.  range 0==darkest, 1==brightest
  306. * dir == +1 or -1 from current or if
  307. * absolute is set, then torch <- absolute
  308. *************************************************************************/
  309. void Brightness(short dir,short absolute)
  310. {
  311.     torch+=dir;
  312.     if (absolute) torch=absolute;
  313.     if (torch<0) torch=0; else
  314.     if (torch>6) torch=6;
  315.     heighttolight=htab[torch];
  316. }
  317.  
  318. /**************************************************************************
  319. * BlitLine.  x is the pixel column to draw the line at.
  320. * Draws a 1-pixel-width vertical line of "1"s into the fifth bitplane
  321. * where the palette changes.  This way, BlitFill can fill the entire fifth
  322. * bitplane with 1s and 0s alternating after every vertical line.
  323. *
  324. * This routine is currently not used, because I think move/draw is faster
  325. * on the 3000.  But a 500 version might want this routine.
  326. *
  327. * Not used
  328. **************************************************************************/
  329. void BlitLine(short x)
  330. {
  331.     struct Custom *custom = (void *)0x00dff000;
  332.     OwnBlitter();
  333.     WaitBlit();
  334.     custom->bltcon0 = 0x0bfa || (x&15)<<16;
  335.     custom->bltcon1 = 0x049;
  336.     custom->bltdmod = SBYTESPERROW;
  337.     custom->bltcmod = SBYTESPERROW;
  338.     custom->bltamod = 0xfed4;
  339.     custom->bltdpt  = (APTR)((UBYTE *)rp->BitMap->Planes[4]+(x/16)*2);
  340.     custom->bltcpt  = (APTR)((UBYTE *)rp->BitMap->Planes[4]+(x/16)*2);
  341.     custom->bltapt  = (APTR)0xffffff6a;
  342.     custom->bltadat = 0x8000;
  343.     custom->bltbdat = 0xffff;
  344.     custom->bltsize = 1302;
  345.     DisownBlitter();
  346. }
  347.  
  348. /**************************************************************************
  349. * Toggles resolution between hires and lores.
  350. **************************************************************************/
  351. void ToggleRes()
  352. {
  353.       halfres^=1;
  354.  
  355.       if(halfres)
  356.       {
  357.         fastbm.BytesPerRow=SCREENX>>4;
  358.         fastbm.Rows=SCREENY/2;
  359.         rowlook=&rowlookLR[0];
  360.     } else
  361.     {
  362.         fastbm.BytesPerRow=SCREENX>>3;
  363.         fastbm.Rows=SCREENY;
  364.         rowlook=&rowlookHR[0];
  365.     }
  366. }
  367.  
  368. /**************************************************************************
  369. * Takes in start and end coords of line segement.  clips it to the screen.
  370. * Then calls megamap (see megamap.c) to use breshenhams to check to see
  371. * if each point on the line is higher than what was in Map.height, before.
  372. * if the point is higher, it overwrites map[i].height and sets the other
  373. * fields in map, too.
  374. **************************************************************************/
  375. void Line(float sx,float sy,float dx,float dy)
  376. {
  377. short i,temp;
  378. float m;
  379. float deltx;
  380.     sx*=ASPECT; dx*=ASPECT;
  381.  
  382.     deltx=dx-sx;
  383.     if (deltx==0)
  384.     {
  385.         deltx=0.0000001;
  386.         m=1e100;
  387.     } else m=(dy-sy)/deltx;
  388.     if (m==0) m=0.00000001;
  389.  
  390.      intowall=outofwall=0;
  391.     if (sx<-1) {
  392.         intowall=-(sx+1)*WALLWIDTH/deltx;
  393.         sx=-1;
  394.         sy=m*(sx-dx)+dy;
  395.  
  396.     }
  397.     if (sx>1) {
  398.         sx=1;
  399.         sy=m*(sx-dx)+dy;
  400.     }
  401.     if (dx<-1) {
  402.         dx=-1;
  403.         dy=m*(dx-sx)+sy;
  404.     }
  405.     if (dx>1) {
  406.         outofwall = (dx-1)*WALLWIDTH/deltx;
  407.         dx=1;
  408.         dy=m*(dx-sx)+sy;
  409.     }
  410.  
  411.     if (sx>1 || sx<-1 || dx>1 || dx<-1) return;
  412.  
  413. /*  Sx...Dy are pixel values of the line segment */
  414.  
  415.     if (halfres)
  416.     {
  417.         Sx = (sx+1)*(SCREENX>>2);
  418.         Dx = (dx+1)*(SCREENX>>2);
  419.         Sy = (1-sy)*(SCREENY<<4);
  420.         Dy = (1-dy)*(SCREENY<<4);
  421.         intowall>>=1;
  422.         outofwall>>=1;
  423.     } else
  424.     {
  425.         Sx = (sx+1)*(SCREENX>>1);
  426.         Dx = (dx+1)*(SCREENX>>1);
  427.         Sy = (1-sy)*(SCREENY<<5);
  428.         Dy = (1-dy)*(SCREENY<<5);
  429.     }
  430.  
  431.     if (Sx==Dx && Sy==Dy) return;
  432.  
  433. /*  if (Sy>map[Sx].height && Dy>map[Dx].height) return; */
  434. /*  used in megamap.c for breshenhams line algortihm */
  435.     delx = Dx - Sx;
  436.     dely = Dy - Sy;
  437.     e = ABS(dely>>1)-delx;
  438.     s2 = (dely<0) ? -1 : 1;
  439.  
  440.     MegaMap(Sx, delx, Sx, Sy);
  441. }
  442.  
  443.  
  444. /**************************************************************************
  445. * Translates and rotates all the points in the dungeon each frame.
  446. **************************************************************************/
  447. void TransRot()
  448. {
  449. register int i;
  450. register float *rp,*p;
  451. register float p1,p2;
  452.  
  453.     for (i=0;i<numpoints;i++)
  454.     {
  455.         rp=rotpoints[i];
  456.         p=points[i];
  457.         p1=p[0]-transX;
  458.         p2=p[2]-transY;
  459.         rp[0] = p1*cy - p2*sy;
  460.         rp[1] = p[1];
  461.         rp[2] = p1*sy + p2*cy;
  462.     }
  463. }
  464.  
  465. /**************************************************************************
  466. * This routine 1) rotates and translates the points in the dungeon
  467. * 2) Calls "line" which checks to see if each line is at least partially
  468. * and adds it to the Map if it is.
  469. **************************************************************************/
  470. void DrawScene()
  471. {
  472. short i,j,current,xmin,xmax;
  473. float z1,z2,x1,x2,y1,y2,t;
  474. short pt1,pt2;
  475.  
  476.     Frames++;
  477.     clearmapheight();
  478.     TransRot();
  479.  
  480.     for (i=0;i<numedges;i++) {
  481.         pt1=edges[i][0]-1;
  482.         pt2=edges[i][1]-1;
  483.  
  484.         bitmapno=edges[i][2];
  485.         x1= rotpoints[pt1][0];
  486.         y1= rotpoints[pt1][1];
  487.         z1= rotpoints[pt1][2];
  488.         x2= rotpoints[pt2][0];
  489.         y2= rotpoints[pt2][1];
  490.         z2= rotpoints[pt2][2];
  491.         if (z1>0 || z2>0)
  492.         {
  493.             if (z1<0) {
  494.                 t=-z1/(z1-z2);
  495.                 z1=0.00000001;
  496.                 x1=x1+(x1-x2)*t;
  497.                 y1=y1+(y1-y2)*t;
  498.             }
  499.             if (z2<0) {
  500.                 t=-z1/(z1-z2);
  501.                 z2=0.00000001;
  502.                 x2=x1+(x1-x2)*t;
  503.                 y2=y1+(y1-y2)*t;
  504.             }
  505.  
  506.             if (x1/z1 < x2/z2)
  507.                 Line((float)(x1/z1),(float)(y1/z1),(float)(x2/z2),(float)(y2/z2));
  508.             else
  509.                 Line((float)(x2/z2),(float)(y2/z2),(float)(x1/z1),(float)(y1/z1));
  510.         }
  511.     }
  512.  
  513.     if (!speed) PlotYou();
  514.     cpuclear(lines,SBYTESPERROW);
  515.     makelightcolor();
  516.  
  517. }
  518.  
  519. /**************************************************************************
  520. * Reads "dungeon" file into points and edges arrays.
  521. **************************************************************************/
  522. void ReadScene()
  523. {
  524. char line[256];
  525. short mode=0,i;
  526. int num;
  527. int t1,t2,t3,t4,t5,t6,t7;
  528. BYTE b4,b5,b6,b7;
  529. FILE *fp;
  530.  
  531.     fp=fopen(filename,"r");
  532.     if (!fp) { printf("Could not open file %s.\n",filename); return; }
  533.     for (;;)
  534.     {
  535.         if (!fgets(line,50,fp)) {
  536.             printf("error in infile format!\n");
  537.             exit(1);
  538.         }
  539.         line[strlen(line)-1] = '\0';
  540.         if (strlen(line)<2) continue;
  541.         if (!strcmp(line,"END")) break;
  542.         if (!strncmp(line,"POINTS",6)) {
  543.             mode=1;
  544.             continue;
  545.         }
  546.         if (!strncmp(line,"EDGES",5)) {
  547.             mode=2;
  548.             continue;
  549.         }
  550.         if (!strncmp(line,"BUTTONS",5)) {
  551.             mode=3;
  552.             continue;
  553.         }
  554.         switch (mode) {
  555.             case 0: printf("error in infile format!\n");
  556.                     exit(1);
  557.                     break;
  558.             case 1: /*sscanf(line,"%d %f %f %f",&num,&points[numpoints][0],
  559.                         &points[numpoints][1],&points[numpoints][2]); */
  560.                     num = atoi(strtok(line," "));
  561.                     points[numpoints][0]= 1.5 * atof((char *)strtok(NULL," "));
  562.                     points[numpoints][1]= 0.6 * atof((char *)strtok(NULL," "));
  563.                     points[numpoints][2]= 1.5 * atof((char *)strtok(NULL," "));
  564.                     numpoints++;
  565.                     break;
  566.             /* num<edge#> t1<pt1> t2<pt2> t3<wall#> t4<doortype> t5<key> t6<dir> */
  567.             case 2: sscanf(line,"%d %d %d %d %d %d %d",&num,&t1,&t2,&t3,&t4,&t5,&t6);
  568.                     edges[numedges][0]=t1;
  569.                     edges[numedges][1]=t2;
  570.                     edges[numedges][2]=t3;
  571.                     b4=t4; b5=t5, b6=t6;
  572.                     if (b4>0) InsertDoor(numedges,b4,b5,b6);
  573.                     numedges++;
  574.                     break;
  575.             /* <edge#> <dir> <start_state> <press_out_wall#> <press_in_wall#> <y> */
  576.             case 3: sscanf(line,"%d %d %d %d %d %d",&num, &t1, &t2, &t3, &t4, &t5);
  577.                     InsertButton(num,t1,t2,t3,t4,t5);
  578.                     numbuttons++;
  579.                     break;
  580.             default: printf("error in infile format!\n");
  581.                     exit(1);
  582.                     break;
  583.         }
  584.     }
  585.     printf("%d points, %d edges\n",numpoints,numedges);
  586. }
  587.  
  588. /**************************************************************************
  589. * allocs some chip mem for the bitmap.
  590. **************************************************************************/
  591. void SetUpBitMap(struct BitMap *bm,short x,short y,short depth,short bytesperrow)
  592. {
  593. short i;
  594.  
  595.     InitBitMap(bm,depth,x,y);
  596.     bm->BytesPerRow=bytesperrow;
  597.     bm->Planes[0] = AllocRaster(x,y*depth);
  598.     if(bm->Planes[0] == NULL)
  599.     {
  600.         printf("Error with buffer AllocRaster Plane\n");
  601.         Close_All();
  602.         exit(1);
  603.     }
  604.     for(i=1; i<depth; i++)
  605.         bm->Planes[i]=bm->Planes[0]+bm->BytesPerRow*bm->Rows*i;
  606. }
  607.  
  608.  
  609. struct TagItem mytags[3];
  610.  
  611. ยน/**************************************************************************
  612. * Opens screens, libs, inits stuff, etc.
  613. **************************************************************************/
  614. void Open_All(BOOL reopen, short oldx, short oldy)
  615. {
  616. short i;
  617. PLANEPTR tempptr;
  618.  
  619.     if (!reopen)
  620.     {
  621.         mytags[0].ti_Tag=SA_DisplayID;
  622.         mytags[0].ti_Data=SCREENMODE;
  623.         mytags[1].ti_Tag=SA_Overscan;
  624.         mytags[1].ti_Data=SCREENOVR;
  625.         mytags[2].ti_Tag=TAG_DONE;
  626.         mytags[2].ti_Data=TAG_DONE;
  627.         bm1.Planes[0]=0;
  628.         fastbm.Planes[0]=0;
  629.  
  630.             if (!(IntuitionBase = (struct IntuitionBase *)
  631.             OpenLibrary("intuition.library", 0L)))
  632.               {
  633.                   printf("Intuition Library not found!\n");
  634.                   Close_All();
  635.                   exit(FALSE);
  636.               }
  637.            if (!(GfxBase = (struct GfxBase *)
  638.                OpenLibrary("graphics.library", 0L)))
  639.               {
  640.                   printf("Graphics Library not found!\n");
  641.                   Close_All();
  642.                   exit(FALSE);
  643.               }
  644.         #ifdef    TIMING
  645.           if(!(TimerStuff=(struct MyTimerStuff *)AllocMem(sizeof(struct MyTimerStuff),MEMF_CLEAR|MEMF_PUBLIC)))
  646.         {
  647.             printf("No mem for timings\n");
  648.             Close_All();
  649.             exit(FALSE);
  650.         }
  651.           if(OpenDevice(TIMERNAME,UNIT_ECLOCK,(struct IORequest *)&TimerStuff->tio,0L))
  652.         {
  653.             printf("No timer\n");
  654.             Close_All();
  655.             exit(FALSE);
  656.         } else
  657.         {
  658.             TimerBase=(struct Library *)TimerStuff->tio.tr_node.io_Device;
  659.             TimerStuff->EFreq=ReadEClock(&TimerStuff->time1);
  660.         }
  661.         #endif
  662.     }
  663.  
  664.     if (reopen)
  665.     {
  666.        if (FirstWindow) CloseWindow(FirstWindow);
  667.        if (Screen) {
  668.             /*FreeVPortCopLists(&Screen->ViewPort);*/
  669.             CloseScreen(Screen);
  670.        }
  671.        if (bm1.Planes[0]) FreeRaster(bm1.Planes[0],oldx,oldy*DEPTH);
  672.        if (fastbm.Planes[0]) FreeMem(fastbm.Planes[0],(oldx>>3)*4*(oldy));
  673.     }
  674.  
  675.     SetUpBitMap(&bm1,SCREENX,SCREENY,DEPTH,SBYTESPERROW);
  676.     SuperScreen.CustomBitMap=&bm1;
  677.     SuperScreen.Width=SCREENX;
  678.     SuperScreen.Height=SCREENY-1;
  679.     SuperScreen.Extension = mytags;
  680.  
  681.        if (!(Screen = (struct Screen *)
  682.         OpenScreen((struct NewScreen *)&SuperScreen)))
  683.           {
  684.               printf("Screen1 has no page!\n");
  685.               Close_All();
  686.               exit(FALSE);
  687.           }
  688.  
  689.        FirstNewWindow.Screen = Screen;
  690.        FirstNewWindow.Width=SCREENX;
  691.        FirstNewWindow.Height=SCREENY-1;
  692.        if (!(FirstWindow = (struct Window *)
  693.            OpenWindow(&FirstNewWindow)))
  694.           {
  695.               printf("Window1 will not open!\n");
  696.               Close_All();
  697.               exit(FALSE);
  698.           }
  699.  
  700.        rp=FirstWindow->RPort;
  701. /*     SetWrMsk(rp,16); */
  702.     SetAPen(rp,16);
  703.     SetDrMd(rp,JAM1);
  704.  
  705.     for (i=0; i<(1<<DEPTH); i++)
  706.     {
  707.         SetRGB4(&Screen->ViewPort,i,(palette[i]&0xf00)>>8,
  708.         (palette[i]&0x0f0)>>4,(palette[i]&0x00f));
  709.     }
  710.     SetRGB4(&Screen->ViewPort,0,0,0,4);
  711.     SetRGB4(&Screen->ViewPort,16,0,0,4);
  712.     fastbm.Rows=SCREENY;
  713.     fastbm.BytesPerRow=SCREENX>>3;
  714.     fastbm.Planes[0]=AllocMem((SCREENX>>3)*4*(SCREENY),0);
  715.     if (!fastbm.Planes[0]) {
  716.         printf("Could not get fast ram for screen buffer!\n");
  717.         Close_All();
  718.         exit(1);
  719.     }
  720.  
  721.     ShowTitle(Screen,0);
  722.     if(reopen) MakeTables();
  723.  
  724. }
  725.  
  726. void CleanItUp()
  727. {
  728. }
  729.  
  730. /**************************************************************************
  731. * Close all stuff.
  732. **************************************************************************/
  733. void Close_All()
  734.   {
  735. #ifdef TIMING
  736.   if(TimerStuff) {
  737.     if(TimerBase) CloseDevice((struct IORequest *)&TimerStuff->tio);
  738.     FreeMem(TimerStuff,sizeof(struct MyTimerStuff));
  739.     }
  740. #endif
  741.    if (FirstWindow)     CloseWindow(FirstWindow);
  742.    if (Screen) {
  743.         FreeVPortCopLists(&Screen->ViewPort);
  744.         CloseScreen(Screen);
  745.    }
  746. /* if (mapwindow)        CloseWindow(mapwindow); */
  747. /* if (mapscreen)        CloseScreen(mapscreen); */
  748.    if (bm1.Planes[0]) FreeRaster(bm1.Planes[0],SCREENX,SCREENY*DEPTH);
  749. /* if (mapbm.Planes[0])    FreeRaster(mapbm.Planes[0],mapbm.BytesPerRow<<3,mapbm.Rows*mapbm.Depth); */
  750.    if (fastbm.Planes[0]) FreeMem(fastbm.Planes[0],(SCREENX>>3)*4*(SCREENY));
  751.    if (GfxBase)         CloseLibrary((struct Library *)GfxBase);
  752.    if (IntuitionBase)   CloseLibrary((struct Library *)IntuitionBase);
  753. }
  754.  
  755.  
  756. /**************************************************************************
  757. * This routine sets up a lookup table to speed up the main inner loop of
  758. * the drawing program, used in megadraw.c
  759. **************************************************************************/
  760. void MakeTables()
  761. {
  762. short i,j,sy;
  763. short locscreeny;
  764. long size;
  765.  
  766.     SetAPen(rp,4);
  767.     Move(rp,(screenx-21*8)/2,35);
  768.     Text(rp,"Calculating Tables...",21);
  769.  
  770.     locscreeny=SCREENY;
  771.     size=locscreeny*locscreeny*2*4;
  772.     rowlook=&rowlookHR[0];
  773.  
  774.     for (i=0; i<locscreeny; i++)
  775.         for (sy=-locscreeny*3/2; sy<locscreeny/2; sy++)
  776.             rowlook[i+256*(sy+locscreeny*3/2)]=
  777.                 ((i-sy)*WALLHEIGHT/(locscreeny-2*sy))*WALLWIDTH;
  778.     locscreeny=SCREENY/2;
  779.     rowlook=&rowlookLR[0];
  780.  
  781.     for (i=0; i<locscreeny; i++)
  782.         for (sy=-locscreeny*3/2; sy<locscreeny/2; sy++)
  783.             rowlook[i+256*(sy+locscreeny*3/2)]=
  784.                 ((i-sy)*WALLHEIGHT/(locscreeny-2*sy))*WALLWIDTH;
  785.  
  786.     if(halfres) rowlook=&rowlookLR[0]; else rowlook=&rowlookHR[0];
  787.  
  788.     Move(rp,(screenx-21*8)/2,35);
  789.     SetDrMd(rp,JAM2);
  790.     Text(rp,"Done.                ",21);
  791.     SetDrMd(rp,JAM1);
  792. }
  793.  
  794.  
  795. /**************************************************************************
  796. * This routine loads the copper instructions to make the background
  797. * change colors, and reflect the screen.
  798. * In the future, the reflection must either be done by the blitter (on the
  799. * 500) or by the CPU during copy-out on the 3000+.  When that is done,
  800. * comment out the lines, indicated below.
  801. * Now the reflection is done in the copy-out phase by the cpu.  Unccomment
  802. * out the part below to have it done by the copper.
  803. **************************************************************************/
  804. void LoadCopper()
  805. {
  806.     struct Custom *custom = (void *)0x00dff000;
  807.     uCopList= (struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_PUBLIC|MEMF_CLEAR);
  808.     CINIT(uCopList,128);
  809.     CWAIT(uCopList,SCREENY/4,0);
  810.     CMOVE(uCopList,(custom->color[0]),(WORD)0x003);
  811.     CMOVE(uCopList,(custom->color[16]),(WORD)0x003);
  812.     CWAIT(uCopList,SCREENY*3/8,0);
  813.     CMOVE(uCopList,(custom->color[0]),(WORD)0x002);
  814.     CMOVE(uCopList,(custom->color[16]),(WORD)0x002);
  815.     CWAIT(uCopList,SCREENY*7/16,0);
  816.     CMOVE(uCopList,(custom->color[0]),(WORD)0x001);
  817.     CMOVE(uCopList,(custom->color[16]),(WORD)0x001);
  818.     CWAIT(uCopList,SCREENY*15/32,0);
  819.     CMOVE(uCopList,(custom->color[0]),(WORD)0x000);
  820.     CMOVE(uCopList,(custom->color[16]),(WORD)0x000);
  821.     CWAIT(uCopList,SCREENY-SCREENY*15/32,0);
  822.     CMOVE(uCopList,(custom->color[0]),(WORD)0x010);
  823.     CMOVE(uCopList,(custom->color[16]),(WORD)0x010);
  824.     CWAIT(uCopList,SCREENY-SCREENY*7/16,0);
  825.     CMOVE(uCopList,(custom->color[0]),(WORD)0x020);
  826.     CMOVE(uCopList,(custom->color[16]),(WORD)0x020);
  827.     CWAIT(uCopList,SCREENY-SCREENY*3/8,0);
  828.     CMOVE(uCopList,(custom->color[0]),(WORD)0x030);
  829.     CMOVE(uCopList,(custom->color[16]),(WORD)0x030);
  830.     CWAIT(uCopList,SCREENY-SCREENY/4,0);
  831.     CMOVE(uCopList,(custom->color[0]),(WORD)0x040);
  832.     CMOVE(uCopList,(custom->color[16]),(WORD)0x040);
  833.  
  834.     CEND(uCopList);
  835.     Forbid();
  836.     if (Screen->ViewPort.UCopIns==NULL) Screen->ViewPort.UCopIns=uCopList;
  837.     else printf("Error setting up Copper List\n");
  838.     Permit();
  839.     MakeScreen(Screen);
  840.     RethinkDisplay();
  841. }
  842.  
  843.  
  844. /**************************************************************************
  845. * Init routine.  Opens Mapscreen and stuff.
  846. **************************************************************************/
  847. void SetUpMap()
  848. {
  849.     short i,j;
  850.  
  851.     SetUpBitMap(&mapbm,320,80,2,320>>3);
  852.     MapNewScreen.CustomBitMap=&mapbm;
  853.  
  854.     if (!(mapscreen = (struct Screen *)OpenScreen(&MapNewScreen)))
  855.     {
  856.         printf("MapScreen has no page!\n");
  857.         Close_All();
  858.         exit(FALSE);
  859.     }
  860.  
  861.     MapNewWindow.Screen = mapscreen;
  862.  
  863.     if (!(mapwindow = (struct Window *)OpenWindow(&MapNewWindow)))
  864.     {
  865.         printf("MapWindow will not open!\n");
  866.         Close_All();
  867.         exit(FALSE);
  868.     }
  869.  
  870.     maprp=mapwindow->RPort;
  871.     ShowTitle(mapscreen,0);
  872.     MoveScreen(mapscreen,0,150);
  873.     PlotMap();
  874. }
  875.  
  876. /**************************************************************************
  877. * I guess this draws the top view of the map for PlotYou.
  878. **************************************************************************/
  879. void PlotMap()
  880. {
  881.     short i,pt1,pt2,sx,sy,dx,dy;
  882.     SetAPen(maprp,1);
  883.     for    (i=0;i<numedges;i++) {
  884.         pt1=edges[i][0]-1;
  885.         pt2=edges[i][1]-1;
  886.         sx=points[pt1][0]*35/6+80;
  887.         sy=40-points[pt1][2]*30/6;
  888.         dx=points[pt2][0]*35/6+80;
  889.         dy=40-points[pt2][2]*30/6;
  890.         Move(maprp,sx,sy);
  891.         Draw(maprp,dx,dy);
  892.     }
  893. }
  894.  
  895. /**************************************************************************
  896. * This routine is not currently used.  If you put it back in, it will draw
  897. * the top view of the dungeon, but you will always be in the center, and
  898. * the rest of the dungeon will rotate and move around you.
  899. **************************************************************************/
  900. void PlotRotMap()
  901. {
  902.     short i,pt1,pt2,sx,soy,dx,dy;
  903.     float Dx,Sx,Dz,Sz;
  904.  
  905.     SetAPen(maprp,0);
  906.     RectFill(maprp,160,0,319,79);
  907.     SetAPen(maprp,1);
  908.  
  909.     for    (i=0;i<numedges;i++) {
  910.         pt1=edges[i][0]-1;
  911.         pt2=edges[i][1]-1;
  912.         Sx=points[pt1][0];
  913.         Sz=points[pt1][2];
  914.         Dx=points[pt2][0];
  915.         Dz=points[pt2][2];
  916.         sx=(Sx*cy-Sz*sy)*30/6+240;
  917.         soy=40-(Sx*sy+Sz*cy)*25/6;
  918.         dx=(Dx*cy-Dz*sy)*30/6+240;
  919.         dy=40-(Dx*sy+Dz*cy)*25/6;
  920.         Move(maprp,sx,soy);
  921.         Draw(maprp,dx,dy);
  922.     }
  923. }
  924.  
  925. /**************************************************************************
  926. * This routine just plots the overhead view of the dungeon.  It draws a box
  927. * around you, with a white line inside of it pointing in the direction that
  928. * you are facing.  The "s" key will disable this from being drawn during the
  929. * game to speed things up.  This routine only draws to the "mapscreen".
  930. **************************************************************************/
  931. void PlotYou()
  932. {
  933.     static short savex,savey,savex1,savey1;
  934.     short x,y,x1,y1;
  935.     x=transX*35/6+80;
  936.     y=40-transY*30/6;
  937.  
  938.     y1=y-cos(angle*FIX)*BOX;
  939.     x1=x+sin(angle*FIX)*BOX;
  940.  
  941.     SetAPen(maprp,0);
  942.     Move(maprp,savex,savey);
  943.     Draw(maprp,savex1,savey1);
  944.  
  945.     Move(maprp,(long)(savex+BOX),(long)(savey-BOX));
  946.     Draw(maprp,(long)(savex+BOX),(long)(savey+BOX));
  947.     Draw(maprp,(long)(savex-BOX),(long)(savey+BOX));
  948.     Draw(maprp,(long)(savex-BOX),(long)(savey-BOX));
  949.     Draw(maprp,(long)(savex+BOX),(long)(savey-BOX));
  950.  
  951.     SetAPen(maprp,2);
  952.     Move(maprp,x,y);
  953.     Draw(maprp,x1,y1);
  954.     SetAPen(maprp,3);
  955.  
  956.     Move(maprp,(long)(x+BOX),(long)(y-BOX));
  957.     Draw(maprp,(long)(x+BOX),(long)(y+BOX));
  958.     Draw(maprp,(long)(x-BOX),(long)(y+BOX));
  959.     Draw(maprp,(long)(x-BOX),(long)(y-BOX));
  960.     Draw(maprp,(long)(x+BOX),(long)(y-BOX));
  961.  
  962.     savex=x; savey=y;
  963.     savex1=x1; savey1=y1;
  964. }
  965.  
  966. /**************************************************************************
  967. * This routine checks to see if any of the points in the dungeon are inside
  968. * a small box around your current location.  If any are, then it returns
  969. * a value that says that you can't move in the current direction, because
  970. * it would put you inside a wall.
  971. * Returns edge number of the point in the box.  If that edge<numedges,
  972. * then that point is a midpoint.
  973. **************************************************************************/
  974. short PointInBox(float x,float y)
  975. {
  976. float x1,x2,y1,y2;
  977. register short i;
  978. register float *sptemp;
  979.  
  980.     x1 = x-0.62+100;
  981.     x2 = x+0.62+100;
  982.     y1 = y-0.62+100;
  983.     y2 = y+0.62+100;
  984.  
  985.     for (i=0;i<numpoints+numedges;i++) {
  986.         sptemp=subpoints[i];
  987.         if (sptemp[0]>x1 && sptemp[0]<x2 &&
  988.             sptemp[2]>y1 && sptemp[2]<y2) {
  989.             return i;
  990.         }
  991.     }
  992.     return 0;
  993. }
  994.  
  995. short inside=0;
  996. /**************************************************************************
  997. * Subdivides each edge to find midpoint and stores the midpoint in the
  998. * points array.  Midpoints block you from walking through the centers
  999. * of walls.
  1000. **************************************************************************/
  1001. void SubDivide()
  1002. {
  1003. short i,j;
  1004. short pt1,pt2;
  1005.     for (i=0;i<numedges;i++)
  1006.     {
  1007.         pt1=edges[i][0]-1;
  1008.         pt2=edges[i][1]-1;
  1009.  
  1010.         subpoints[i][0]=(points[pt1][0]+points[pt2][0])/2+100;
  1011.         subpoints[i][2]=(points[pt1][2]+points[pt2][2])/2+100;
  1012.     }
  1013.     for (i=0;i<numpoints;i++)
  1014.     {
  1015.         subpoints[i+numedges][0]=points[i][0]+100;
  1016.         subpoints[i+numedges][1]=points[i][1]+100;
  1017.         subpoints[i+numedges][2]=points[i][2]+100;
  1018.     }
  1019. }
  1020.  
  1021. float oldtransX=0;
  1022. float oldtransY=0;
  1023. short a,b,testitem=-1;
  1024. char c;
  1025. float distance, distance1, oldangle, deltaangle;
  1026. short resmode=0;
  1027.  
  1028. /**************************************************************************
  1029. * Returns the direction something is facing from a given angle.
  1030. **************************************************************************/
  1031. BYTE Direction(float angle)
  1032. {
  1033.     if (angle>314 || angle<45) return NORTH;
  1034.     if (angle>44 && angle<135) return EAST;
  1035.     if (angle>134 && angle<225) return SOUTH;
  1036.     if (angle>224 && angle<315) return WEST;
  1037. }
  1038.  
  1039. /**************************************************************************
  1040. * Makes 8 light tables (one for each possible shifted position) Used
  1041. * to remove a shift instruction from the innermost megadraw i-loop.
  1042. **************************************************************************/
  1043. void MakeLightTable() {
  1044.     short i,j;
  1045.  
  1046.     /* This makes the lighttable have shifted values to save 1 instruction
  1047.     in megadraw */
  1048.  
  1049.     lighttable=(ULONG *)malloc(16*16*4*8);
  1050.     if(!lighttable) {
  1051.         printf("could not alloc lighttable\n");
  1052.           exit(1);
  1053.     }
  1054.     for(i=0;i<8;i++)
  1055.         for(j=0;j<16*16;j++)
  1056.             lighttable[i*16*16+j]=lighttable_base[j]<<i;
  1057. }
  1058.  
  1059.  
  1060. /**************************************************************************
  1061. * choose screenx, screeny
  1062. **************************************************************************/
  1063. void ChooseSize(BOOL first)
  1064. {
  1065. short i,j,tempx=256,tempy=128;
  1066. ULONG class;
  1067. USHORT code;
  1068. struct IntuiMessage  *message1;
  1069. short oldx,oldy;
  1070. char  text[256];
  1071.  
  1072.     oldx=screenx;oldy=screeny;
  1073.  
  1074.     SetAPen(rp,0);
  1075.     RectFill(rp,0,0,screenx,screeny);
  1076.     SetAPen(rp,14);
  1077.     RectFill(rp,0,0,tempx,tempy);
  1078.     SetAPen(rp,2);
  1079.     Move(rp,(screenx-18*8)/2,20);
  1080.     Text(rp,"Select Screen Size",18);
  1081.     Move(rp,(screenx-20*8)/2,30);
  1082.     Text(rp,"Using Numeric Keypad",20);
  1083.     Move(rp,(screenx-20*8)/2,40);
  1084.     Text(rp,"Press Space to begin",20);
  1085.     sprintf(text,"Now: %d by %d",tempx,tempy);
  1086.     Move(rp,(screenx-strlen(text)*8)/2,50);
  1087.     Text(rp,text,strlen(text));
  1088.  
  1089.     FOREVER
  1090.     {
  1091.         if ((message1 = (struct IntuiMessage *)GetMsg(FirstWindow->UserPort)) == NULL)
  1092.         {
  1093.             Wait(1L << FirstWindow->UserPort->mp_SigBit);
  1094.             continue;
  1095.         }
  1096.         class = message1->Class;
  1097.         code = message1->Code;
  1098.         ReplyMsg((struct Message *)message1);
  1099.         if (class & VANILLAKEY)
  1100.         {
  1101.             if (code==' ') break;
  1102.             else if (code=='8') tempy-=32;
  1103.             else if (code=='2') tempy+=32;
  1104.             else if (code=='4') tempx-=32;
  1105.             else if (code=='6') tempx+=32;
  1106.             else if (code=='5') { tempx=256; tempy=128; }
  1107.             else if (code=='7') { tempx-=32; tempy-=32; }
  1108.             else if (code=='9') { tempx+=32; tempy-=32; }
  1109.             else if (code=='1') { tempx-=32; tempy+=32; }
  1110.             else if (code=='3') { tempx+=32; tempy+=32; }
  1111.             if (tempx<64) tempx=64;
  1112.             if (tempy<64) tempy=64;
  1113.             if (tempx>352) tempx=352;
  1114.             if (tempy>224) tempy=224;
  1115.  
  1116.             SetAPen(rp,0);
  1117.             RectFill(rp,0,0,screenx,screeny);
  1118.             SetAPen(rp,14);
  1119.             RectFill(rp,0,0,tempx,tempy);
  1120.             SetAPen(rp,2);
  1121.             Move(rp,(screenx-18*8)/2,20);
  1122.             Text(rp,"Select Screen Size",18);
  1123.             Move(rp,(screenx-20*8)/2,30);
  1124.             Text(rp,"Using Numeric Keypad",20);
  1125.             Move(rp,(screenx-20*8)/2,40);
  1126.             Text(rp,"Press Space to begin",20);
  1127.             sprintf(text,"Now: %d by %d",tempx,tempy);
  1128.             Move(rp,(screenx-strlen(text)*8)/2,50);
  1129.             Text(rp,text,strlen(text));
  1130.         }
  1131.     }
  1132.     screenx=tempx;
  1133.     screeny=tempy;
  1134.     x2=SCREENX/2; y2=SCREENY/2;
  1135.     Open_All(1,oldx,oldy);
  1136. }
  1137.  
  1138. main(int argc,char **argv)
  1139. {
  1140. short i,j,xauto=0,yauto=0,zauto=0;
  1141. float xplus,yplus,zplus;
  1142. ULONG class;
  1143. USHORT code;
  1144. int oldx,oldy;
  1145. int rot=0;
  1146. float addx, addy;
  1147. struct IntuiMessage  *message;
  1148. APTR tempbmp;
  1149. struct ViewPort *vp;
  1150. short offangle=0;
  1151. float forward=0;
  1152.  
  1153.     rowlookHR = (ULONG *)malloc (256 * 512 * sizeof(ULONG));
  1154.     rowlookLR = (ULONG *)malloc (256 * 512 * sizeof(ULONG));
  1155.     if (rowlookHR==0 || rowlookLR==0) {
  1156.         printf("not enough memory for internal arrays.\n");
  1157.         exit(1);
  1158.     }
  1159.     loadwalls();
  1160.     screenx=352;
  1161.     screeny=224;
  1162.     x2=SCREENX/2; y2=SCREENY/2;
  1163.     Open_All(0,0,0);
  1164.     ChooseSize(1);
  1165.     if (argc!=2) strcpy(filename,"dungeon"); else strcpy(filename,argv[1]);
  1166.     ReadScene();
  1167.     SubDivide();
  1168.     MakeLightTable();
  1169.     vp=&Screen->ViewPort;
  1170.     Brightness(0,3);
  1171. /*    LoadItems();*/
  1172.  
  1173.     LoadCopper();
  1174.     forward= ((SCREENY/2 - y2)/5);
  1175.     forward/=30;
  1176.     offangle = (x2 - SCREENX/2)/6;
  1177.     angle += offangle;
  1178.     if (angle<0)   angle+=360; else
  1179.     if (angle>360) angle=angle-360;
  1180.     cy=cos(angle*FIX);
  1181.     sy=sin(angle*FIX);
  1182.     transY+=cy*forward;
  1183.     transX+=sy*forward;
  1184.     cpuclear((void *)fastbm.Planes[0],fastbm.BytesPerRow*4*fastbm.Rows);
  1185.     DrawScene();
  1186.     Fill();
  1187.     if(halfres) fasttochip2(&bm1); else  fasttochip(&bm1);
  1188.     SetAPen(rp,1);
  1189.     Move(rp,(screenx-18*8)/2,10);
  1190.     Text(rp,"Rotation Demo V3.0",18);
  1191.     Move(rp,(screenx-8*8)/2,20);
  1192.     Text(rp,"(c) 1993",8);
  1193.     Move(rp,(screenx-12*8)/2,40);
  1194.     Text(rp,"Jason Freund",12);
  1195.     Move(rp,(screenx-11*8)/2,50);
  1196.     Text(rp,"Gabe Dalbec",11);
  1197.     SetAPen(rp,4);
  1198.     Move(rp,(screenx-18*8)/2,11);
  1199.     Text(rp,"Rotation Demo V3.0",18);
  1200.     Move(rp,(screenx-8*8)/2,21);
  1201.     Text(rp,"(c) 1993",8);
  1202.     Move(rp,(screenx-12*8)/2,41);
  1203.     Text(rp,"Jason Freund",12);
  1204.     Move(rp,(screenx-11*8)/2,51);
  1205.     Text(rp,"Gabe Dalbec",11);
  1206.  
  1207.     if(screeny>64) {
  1208.         SetAPen(rp,1);
  1209.         Move(rp,(screenx-11*8)/2,60);
  1210.         Text(rp,"Chris Hames",11);
  1211.         Move(rp,(screenx-18*8)/2,70);
  1212.         Text(rp,"Click LMB to Start",18);
  1213.  
  1214.         SetAPen(rp,4);
  1215.         Move(rp,(screenx-11*8)/2,61);
  1216.         Text(rp,"Chris Hames",11);
  1217.         Move(rp,(screenx-18*8)/2,71);
  1218.         Text(rp,"Click LMB to Start",18);
  1219.     }
  1220.  
  1221. /*    GetInput(&a,&b,&c);*/
  1222.     StartTTimer(); /* Start Total Timer */
  1223.  
  1224.     FOREVER
  1225.     {
  1226.         if ((message = (struct IntuiMessage *)GetMsg(FirstWindow->UserPort)) == NULL)
  1227.         {
  1228.             MoveDoors();
  1229.             angle+=yauto;
  1230.             if (moveok)
  1231.             {
  1232.                 forward= ((SCREENY/2 - y2)/5);
  1233.                 forward/=30;
  1234.                 offangle = (x2 - SCREENX/2)/6;
  1235.                 angle += offangle;
  1236.                 if (angle<0)   angle+=360; else
  1237.                 if (angle>360) angle=angle-360;
  1238.                 cy=cos(angle*FIX);
  1239.                 sy=sin(angle*FIX);
  1240.                 transY+=cy*forward;
  1241.                 transX+=sy*forward;
  1242.                 if (PointInBox(transX,transY))
  1243.                     if (!PointInBox(oldtransX,transY))
  1244.                         transX=oldtransX; else
  1245.                         if (!PointInBox(transX,oldtransY)) transY=oldtransY; else
  1246.                         {
  1247.                             transX=oldtransX;
  1248.                             transY=oldtransY;
  1249.                         }
  1250.             }
  1251. /* auto */  if (resmode==0)
  1252.             {
  1253.                 distance = fabs(transX-oldtransX);
  1254.                 distance *= distance;
  1255.                 distance1 = fabs(transY-oldtransY);
  1256.                 distance1 *= distance1;
  1257.                 distance += distance1;
  1258.                 deltaangle = fabs(offangle);
  1259.                 if (halfres==0 && (deltaangle>6 || distance>0.075)) ToggleRes(); else
  1260.                 if (halfres && (deltaangle<7 || distance<0.075001)) ToggleRes();
  1261.             } else
  1262. /* hires */    if (resmode==1 && halfres) ToggleRes(); else
  1263. /* lores */ if (resmode==2 && halfres==0) ToggleRes();
  1264.             AnimWalls();
  1265.             cpuclear((void *)fastbm.Planes[0],fastbm.BytesPerRow*4*fastbm.Rows);
  1266.             DrawScene();
  1267.             Fill();
  1268.             /* WaitBOVP(vp); */
  1269.             if(halfres) fasttochip2(&bm1); else  fasttochip(&bm1);
  1270. /*            if (testitem>-1) BlitMe(134,30, Items[0][testitem]);*/
  1271.             oldtransX=transX;
  1272.             oldtransY=transY;
  1273.             oldangle = angle;
  1274.             continue;
  1275.         }
  1276.         class = message->Class;
  1277.         code = message->Code;
  1278.         x2=message->MouseX;
  1279.         y2=message->MouseY;
  1280.         if (y2<0) y2=0;
  1281.         if (x2<0) x2=0;
  1282.         if (x2>SCREENX) x2=SCREENX;
  1283.         if (y2>SCREENY) y2=SCREENY;
  1284.         ReplyMsg((struct Message *)message);
  1285.  
  1286.         if (class & VANILLAKEY)
  1287.         {
  1288.             oldtransX=transX;
  1289.             oldtransY=transY;
  1290.             if (code=='q') break;
  1291.             else if (code=='r') { transY=0; transX=0; angle=0;}
  1292.             else if (code=='5') {
  1293.                 transY-=cos(angle*FIX)*.2;
  1294.                 transX-=sin(angle*FIX)*.2;
  1295.             }
  1296.             else if (code=='8') {
  1297.                 transY+=cos(angle*FIX)*.2;
  1298.                 transX+=sin(angle*FIX)*.2;
  1299.             }
  1300.             else if (code=='4') {
  1301.                 transX-=cos(angle*FIX)*.1;
  1302.                 transY+=sin(angle*FIX)*.1;
  1303.             }
  1304.             else if (code=='6') {
  1305.                 transX+=cos(angle*FIX)*.1;
  1306.                 transY-=sin(angle*FIX)*.1;
  1307.             }
  1308.             else if (code=='7') angle-=ROTATE;
  1309.             else if (code=='9') angle+=ROTATE;
  1310.             else if (code=='y') yauto++;
  1311.             else if (code=='Y') yauto--;
  1312.             else if (code=='r') PlotMap();
  1313.             else if (code=='s') speed=!speed;
  1314.             else if (code==' ') ActivateDoor();
  1315.             else if (code=='l') resmode=2;
  1316.             else if (code=='a') resmode=0;
  1317.             else if (code=='h') resmode=1;
  1318.             else if (code==',') Brightness(-1,0);
  1319.             else if (code=='.') Brightness(1,0);
  1320.             xplus=0; yplus=0; zplus=0;
  1321.  
  1322.             if (PointInBox(transX,transY))
  1323.                 if (!PointInBox(oldtransX,transY))
  1324.                     transX=oldtransX; else
  1325.                     if (!PointInBox(transX,oldtransY)) transY=oldtransY; else
  1326.                     {
  1327.                         transX=oldtransX;
  1328.                         transY=oldtransY;
  1329.                     }
  1330.  
  1331.         }
  1332.         else if (class & MOUSEBUTTONS)
  1333.         {
  1334.             if (code == SELECTDOWN) {}
  1335.             if (code == SELECTUP) {}
  1336.             if (code == MENUDOWN)
  1337.                 moveok=!moveok;
  1338.             if (code == MENUUP) {}
  1339.         }
  1340.  
  1341.     }
  1342.  
  1343.     EndTTimer(); /* Stop Total Timer - Show fps */
  1344.     printf("screenx %d screeny %d\n",screenx,screeny);
  1345.     printf("pixels %d / sec %lf = %lf\n",(Frames*screenx*screeny),(float)(((TimerStuff->ttime2.ev_lo-TimerStuff->ttime1.ev_lo)/(float)TimerStuff->EFreq)),
  1346.         (Frames*screenx*screeny)/(float)(((TimerStuff->ttime2.ev_lo-TimerStuff->ttime1.ev_lo)/(float)TimerStuff->EFreq)));
  1347.     Close_All();
  1348.     exit(TRUE);
  1349. }
  1350.  
  1351.